# -*- coding: utf-8 -*-
from MTMCException import MTMCException

"""
Eine Implementierung des Observer Design Pattern. 
Im Prinzip ein Interface wie aus der Java-Klasse bekannt. Von dieser Klasse 
sollten alle Observer abeleitet werden.

@author: Philipp Dermitzel
@date: 2011-03-31
@version: 1.0.1
"""
class Observer(object):
    
    """
    Wirft eine Exception, falls die abgeleitete Klasse keine update-Methode 
    bereitstellt.
    """   
    def updateObserver(self, obj):
        raise MTMCException("""Der Observer '%s' implementiert keine 
            update-Mathode. Aufruf durch %s""" %(self, obj), critical=True)
        
"""
Eine Implementierung des Observer Design Pattern. 
Eine Klasse, die von dieser Observable-Klasse abgeleitet wird, kann Events an 
alle Observer abgeben und diese so über Änderungen benachrichtigen. Dabei 
sollten alle Observer von der Klasse Observer abgeleitet werden.

@author: Philipp Dermitzel
@date: 2011-04-03
@version: 1.0.2
"""
class Observable(object):
    
    """
    Der Konstruktor.
    """   
    def __init__(self):
        self.__observers = []
    
    """
    Fügt dem Obserable-Objekt einen weiteren Observer hinzu. Dieser sollte von 
    der Observer-Klasse abgeleitet sein, um Fehler zu verhindern.
    @param observer: Der hinzuzufügende Observer
    @type observer: unknown [Observer]
    """
    def addObserver(self, observer):
        print type(observer)
        if observer not in self.__observers:
            self.__observers.append(observer)
    
    """
    Löscht einen Observer aus der Liste der Listener.
    @param observer: Der zu entfernende Observer
    @type observer: unknown [Observer]
    """
    def removeObserver(self, observer):
        if observer in self.__observers:
            self.__observers.remove(observer)
    
    """
    Benachrichtigt alle Observer und ruft deren C(updateObserver())-Methode auf,
    in welcher das weitere Vorgehen definiert ist.
    """        
    def notifyObserver(self):
        for observer in self.__observers:
            observer.updateObserver(self)
